#include "mainwindow.h"

#include <QDebug>

static const QString apt_conf = "/var/lib/deepin-home-appstore-daemon/apt_custom_v2.conf";
static const QString default_name = "org.videolan.www.vlc";

static const QString check1 = "LANGUAGE=en_US";
static const QString check2 = "PACKAGEKIT_CALLER_UID=1000";

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(600, 400);

    QWidget *mainWidget = new QWidget;
    QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget);
    mainLayout->setContentsMargins(10, 10, 10, 10);
    mainLayout->setSpacing(10);
    setCentralWidget(mainWidget);

    QHBoxLayout *layoutName = new QHBoxLayout;
    layoutName->addWidget(new QLabel("包名："));
    m_lineEditName = new QLineEdit;
    m_lineEditName->setPlaceholderText("必填");
    m_lineEditName->setText(default_name);
    layoutName->addWidget(m_lineEditName);

    QHBoxLayout *layoutVersion = new QHBoxLayout;
    layoutVersion->addWidget(new QLabel("版本："));
    m_lineEditVersion = new QLineEdit;
    m_lineEditVersion->setPlaceholderText("选填");
    layoutVersion->addWidget(m_lineEditVersion);

    m_btnShow = new QPushButton("显示信息");
    m_btnQuery = new QPushButton("查询安装");
    m_btnDownload = new QPushButton("下载");
    m_btnInstall = new QPushButton("安装");
    m_btnPurge = new QPushButton("卸载");

    m_checkBox1 = new QCheckBox(check1);
    m_checkBox2 = new QCheckBox(check2);

    QHBoxLayout *layoutBtn = new QHBoxLayout;
    layoutBtn->addWidget(m_btnShow);
    layoutBtn->addWidget(m_btnQuery);
    layoutBtn->addWidget(m_btnDownload);
    layoutBtn->addWidget(m_btnInstall);
    layoutBtn->addWidget(m_btnPurge);

    mainLayout->addLayout(layoutName);
    mainLayout->addLayout(layoutVersion);
    mainLayout->addWidget(m_checkBox1);
    mainLayout->addWidget(m_checkBox2);
    mainLayout->addLayout(layoutBtn);
    mainLayout->addStretch();

    connect(m_lineEditName, &QLineEdit::textChanged, this, &MainWindow::updateBtnState);
    connect(m_btnShow, &QPushButton::clicked, this, &MainWindow::slotShowClicked);
    connect(m_btnQuery, &QPushButton::clicked, this, &MainWindow::slotQueryClicked);
    connect(m_btnDownload, &QPushButton::clicked, this, &MainWindow::slotDownloadClicked);
    connect(m_btnInstall, &QPushButton::clicked, this, &MainWindow::slotInstallClicked);
    connect(m_btnPurge, &QPushButton::clicked, this, &MainWindow::slotPurgeClicked);

    updateBtnState();
}

MainWindow::~MainWindow() 
{
    delete m_process;
}

void MainWindow::updateBtnState()
{
    if (m_lineEditName->text().isEmpty()) {
        m_btnShow->setEnabled(false);
        m_btnQuery->setEnabled(false);
        m_btnDownload->setEnabled(false);
        m_btnInstall->setEnabled(false);
        m_btnPurge->setEnabled(false);
    } else {
        m_btnShow->setEnabled(true);
        m_btnQuery->setEnabled(true);
        m_btnDownload->setEnabled(true);
        m_btnInstall->setEnabled(true);
        m_btnPurge->setEnabled(true);
    }
}

void MainWindow::slotShowClicked()
{
    qDebug() << "--------------------显示信息---------------------";

    QString package = "^" + m_lineEditName->text() + "$";
    if (!m_lineEditVersion->text().isEmpty()) {
        package += "=" + m_lineEditVersion->text();
    }

    QString cmd = QString("apt-cache -c " + apt_conf + " show %1").arg(package);

    qDebug() << "cmd:" << cmd;

    QProcess process;
    process.start("/bin/bash", {"-c", cmd});
    process.waitForFinished(-1);

    if (process.exitCode() == 0 && process.exitStatus() == QProcess::NormalExit) {
        QString data = process.readAllStandardOutput();
        QStringList dataList = data.split("\n\n");
        int cnt = dataList.size();
        if (cnt >= 1) {
            for (int i = 0; i < cnt; i++) {
                QTextStream out(dataList[i].toLocal8Bit());
                while (!out.atEnd()) {
                    QString lineData = out.readLine();
                    qDebug() << lineData;
                }
            }
        }
    }

    process.close();
}

void MainWindow::slotQueryClicked()
{
    qDebug() << "--------------------查询安装---------------------";

    QProcess process;
    QString cmd = QString("dpkg-query");
    QStringList args;
    args.append("-W");
    args.append("-f=${Package} ${Version} ${Installed-Size} ${db:Status-Status} ${db-fsys:Files}");
    args.append(m_lineEditName->text());

    qDebug() << cmd << args;
    process.start(cmd, args);
    process.waitForFinished(-1);
    
    if (process.exitCode() == 0 && process.exitStatus() == QProcess::NormalExit) {
        QString data = process.readAllStandardOutput();
        QStringList dataList = data.split("\n\n");
        int cnt = dataList.size();
        if (cnt >= 1) {
            for (int i = 0; i < cnt; i++) {
                QTextStream out(dataList[i].toLocal8Bit());
                while (!out.atEnd()) {
                    QString lineData = out.readLine();
                    qDebug() <<lineData;
                }
            }
        }
        qDebug() << "query succeeded~~~~已安装";
    } else {
        qDebug() << "query failed~~~~未安装";
    }
}

void MainWindow::slotDownloadClicked()
{
    qDebug() << "--------------------下载---------------------";

    if (m_process) {
        if (m_process->state() == QProcess::Running) {
            qWarning() << "process running...";
            return;
        }

        disconnect(m_process);
        delete m_process;
        m_process = nullptr;
    }

    m_process = new QProcess();
    connect(m_process, &QProcess::readyReadStandardOutput, this, &MainWindow::OnReadyReadAllStandardOutput, Qt::DirectConnection);
    connect(m_process, &QProcess::readyReadStandardError, this, &MainWindow::OnReadyReadStandardError, Qt::DirectConnection);
    connect(m_process, &QProcess::errorOccurred, this, &MainWindow::OnErrorOccurred, Qt::DirectConnection);
    connect(m_process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &MainWindow::OnDownloadFinishedSlot, Qt::DirectConnection);

    QString cmd = "apt-get.real";
    // QStringList args = QStringList() << "-c"
    //                                     << apt_conf
    //                                     << "-y"
    //                                     << "-d"
    //                                     << "-o"
    //                                     << "Acquire::Retries=1"
    //                                     << "-o"
    //                                     << "APT::Status-Fd=-1"
    //                                     << "-o"
    //                                     << "Debug::acquire::progress=true"
    //                                     << "-o"
    //                                     << "Dpkg::Progress=true"
    //                                     << "-o"
    //                                     << "Debug::NoLocking=1"
    //                                     << "--allow-change-held-packages"
    //                                     << "install";

    QStringList args = QStringList() << "-y" << "-d" << "install";

    QString package = "^" + m_lineEditName->text() + "$";
    if (!m_lineEditVersion->text().isEmpty()) {
        package.append("=" + m_lineEditVersion->text());
    }

    args.append(package);

    // QProcessEnvironment sysnEnv = QProcessEnvironment::systemEnvironment();
    // QStringList env = sysnEnv.toStringList();
    QStringList env ; //= QStringList() << "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";

    if (m_checkBox1->isChecked()) {
        env.append(check1);
        m_process->setEnvironment(env);
    }
    if (m_checkBox2->isChecked()) {
        env.append(check2);
        m_process->setEnvironment(env);
    }
    qDebug() << "env:" << m_process->environment();



    // QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    // env.insert("LANGUAGE", "en_US");
    // m_process->setProcessEnvironment(env);
    // qDebug() << "env:" << m_process->processEnvironment().toStringList();

    qDebug() << cmd << args;
    m_process->start(cmd, args);
}

void MainWindow::slotInstallClicked()
{
    qDebug() << "--------------------安装---------------------";
    
    if (m_process) {
        if (m_process->state() == QProcess::Running) {
            qWarning() << "process running...";
            return;
        }

        disconnect(m_process);
        delete m_process;
        m_process = nullptr;
    }

    m_process = new QProcess();
    connect(m_process, &QProcess::readyReadStandardOutput, this, &MainWindow::OnReadyReadAllStandardOutput, Qt::DirectConnection);
    connect(m_process, &QProcess::readyReadStandardError, this, &MainWindow::OnReadyReadStandardError, Qt::DirectConnection);
    connect(m_process, &QProcess::errorOccurred, this, &MainWindow::OnErrorOccurred, Qt::DirectConnection);
    connect(m_process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &MainWindow::OnInstallFinishedSlot, Qt::DirectConnection);

    QString cmd = "apt-get";
    QStringList args = QStringList() << "-c"
                                     << apt_conf
                                     << "-y"
                                     << "-o"
                                     << "Acquire::Retries=1"
                                     << "-o"
                                     << "APT::Status-Fd=-1"
                                     << "-o"
                                     << "Debug::acquire::progress=true"
                                     << "-o"
                                     << "Dpkg::Progress=true"
                                     << "-o"
                                     << "Debug::NoLocking=1"
                                     << "--allow-change-held-packages"
                                     << "install";

    QString package = "^" + m_lineEditName->text() + "$";
    if (!m_lineEditVersion->text().isEmpty()) {
        package.append("=" + m_lineEditVersion->text());
    }

    args.append(package);

    qDebug() << cmd << args;
    m_process->start(cmd, args);
}

void MainWindow::slotPurgeClicked()
{
    qDebug() << "--------------------卸载---------------------";

    if (m_process) {
        if (m_process->state() == QProcess::Running) {
            qWarning() << "process running...";
            return;
        }

        disconnect(m_process);
        delete m_process;
        m_process = nullptr;
    }

    m_process = new QProcess();
    connect(m_process, &QProcess::readyReadStandardOutput, this, &MainWindow::OnReadyReadAllStandardOutput, Qt::DirectConnection);
    connect(m_process, &QProcess::readyReadStandardError, this, &MainWindow::OnReadyReadStandardError, Qt::DirectConnection);
    connect(m_process, &QProcess::errorOccurred, this, &MainWindow::OnErrorOccurred, Qt::DirectConnection);
    connect(m_process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &MainWindow::OnPurgeFinishedSlot, Qt::DirectConnection);

    QString cmd = "apt-get";
    QStringList args = QStringList() << "-y"
                                     << "-o"
                                     << "APT::Status-Fd=3"
                                     << "-o"
                                     << "Debug::NoLocking=1"
                                     << "--allow-change-held-packages"
                                     << "purge";

    QString package = m_lineEditName->text();
    if (!m_lineEditVersion->text().isEmpty()) {
        package.append("=" + m_lineEditVersion->text());
    }
    args.append(package);

    qDebug() << cmd << args;
    m_process->start(cmd, args);
}

void MainWindow::OnReadyReadAllStandardOutput()
{
    if (m_process == nullptr) {
        return;
    }

    QString output = m_process->readAllStandardOutput();
    qDebug() << output;
}

void MainWindow::OnReadyReadStandardError()
{
    if (m_process == nullptr) {
        return;
    }

    QString err = m_process->readAllStandardError();
    qDebug() << err;
}

void MainWindow::OnErrorOccurred(QProcess::ProcessError error)
{
    qDebug() << error;
}

void MainWindow::OnDownloadFinishedSlot(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << exitCode << exitStatus;

    if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
        qDebug() << "下载成功";
    }
}

void MainWindow::OnInstallFinishedSlot(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << exitCode << exitStatus;

    if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
        qDebug() << "安装成功";
    }
}

void MainWindow::OnPurgeFinishedSlot(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << exitCode << exitStatus;

    if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
        qDebug() << "卸载成功";
    }
}
